package com.compty.core.struts2;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.PrintWriter;
import java.util.Calendar;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;

import com.compty.core.framework.context.spring.SpringContextHolder;
import com.compty.core.framework.util.DateUtil;
import com.compty.core.framework.util.FileUtil;
import com.compty.core.framework.util.StringUtil;
import com.compty.core.page.Page;
import com.compty.core.utils.GenericsUtils;
import com.compty.paint.domain.CatalogType;
import com.compty.paint.domain.CustomerInfo;
import com.compty.paint.domain.ImageInfo;
import com.compty.paint.domain.LogInfo;
import com.compty.paint.domain.Painter;
import com.compty.paint.domain.Painting;
import com.compty.paint.domain.support.CustomerLogTypeEnum;
import com.compty.paint.domain.support.LogTypeEnum;
import com.compty.paint.manager.CatalogTypeManager;
import com.compty.paint.util.Constants;
import com.compty.paint.util.ImageUtil;
import com.compty.security.domain.User;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;


/**
 * 支持ModelDriven的基类.
 * @param <T> 泛型
 */
public class BaseAction<T> extends ActionSupport
    implements ServletRequestAware, ServletResponseAware, ModelDriven<T> {
	
    /** * serial. */
    static final long serialVersionUID = 0L;

    /** * 日志. */
    private static Logger logger = Logger.getLogger(BaseAction.class);

    /** * request. */
    protected transient HttpServletRequest request;

    /** * response. */
    protected transient HttpServletResponse response;

    /** * session. */
    protected transient HttpSession session;

    /** * out. */
    protected transient PrintWriter out;

    /** * 持久类. */
    protected T entity;

    /** * 持久类类型. */
    @SuppressWarnings("unchecked")
	protected Class entityClass;
    
    protected Integer curPage = 1;
    protected Integer pageSize = 10;
    protected String sort;
    protected String dir;
	protected String filterTxt;
	protected String filterValue;
	protected Page page;

    /** * 构造方法. */
    public BaseAction() {
        this.entityClass = GenericsUtils.getSuperClassGenricType(this
                .getClass());
    }

    /** * @param servletRequest HttpServletRequest. */
    public void setServletRequest(HttpServletRequest servletRequest) {
        this.request = servletRequest;
        this.session = this.request.getSession();
    }

    /** * @param servletResponse HttpServletResponse. */
    public void setServletResponse(HttpServletResponse servletResponse) {
        try {
            this.response = servletResponse;

            this.response.setCharacterEncoding("UTF-8");
            this.out = this.response.getWriter();
        } catch (Exception ex) {
            logger.error(ex, ex);
        }
    }

    /** * @return T. */
    @SuppressWarnings("unchecked")
	public T getModel() {
        try {
            if (entity == null) {
                entity = (T) entityClass.newInstance();
            }
        } catch (Exception ex) {
            logger.error(ex, ex);
        }

        return entity;
    }
	
	/**
	 * 创建瓷艺中图B(长方形竖以长为准618像素，长方形横以宽为准618像素，正方形以宽为准618像素)
	 * @param srcpath 原图路径 
	 * @param middleImgBPath 目标图片生成路径
	 * @param sharpId 瓷艺图片形状类型编号
	 */
    protected boolean writeCiyiMiddleImageB(String srcpath, String middleImgBPath,Long sharpId)  throws Exception{
    	
		File f = new File(srcpath);
		if( !f.exists() ){
			return false;
		}
		
		BufferedImage sourceImage = ImageIO.read(f);
		int prevW = sourceImage.getWidth();
        int prevH = sourceImage.getHeight();
        if( sharpId == null ){
        	if(prevW < prevH){
        		sharpId = 2L;
        	}
        	else if(prevW > prevH){
        		sharpId = 3L;
        	}else{
        		sharpId = 1L;
        	}
        }
		
		int targetWidth= 0;
		int targetHeight = 0;
		if(sharpId == 1){//正方形
			if(prevW < 618.00){
				targetWidth = prevW;
				targetHeight = prevH;
			}else{
				targetWidth = 618;
				targetHeight = targetWidth*prevH/prevW;
			}
		}
		else if(sharpId == 2){//长方形(竖)
			if(prevH < 618.00){
				targetWidth = prevW;
				targetHeight = prevH;
			}else{
				targetHeight = 618;
				targetWidth = targetHeight*prevW/prevH;
			}
		}
		else if(sharpId == 3){//长方形(横)
			if(prevW < 618.00){
				targetWidth = prevW;
				targetHeight = prevH;
			}else{
				targetWidth = 618;
				targetHeight = targetWidth*prevH/prevW;
			}
		}
		
		ImageUtil.resize(srcpath,middleImgBPath, targetWidth, targetHeight);
		return true;
	}

	/**
	 * 创建瓷艺大图(限制为750像素)
	 * @param srcpath 原图路径 
	 * @param bigImgPath 目标图片生成路径
	 */
	protected boolean writeCiyiBigImgPath(String srcpath, String bigImgPath, Long sharpId)  throws Exception{
    	
		File f = new File(srcpath);
		if( !f.exists() ){
			return false;
		}
		
		BufferedImage sourceImage = ImageIO.read(f);
		int prevW = sourceImage.getWidth();
        int prevH = sourceImage.getHeight();
		
		int targetWidth= 0;
		int targetHeight = 0;
		if(prevW < 750.00){
			targetWidth = prevW;
			targetHeight = prevH;
		}else{
			targetWidth = 750;
			targetHeight = targetWidth*prevH/prevW;
		}
		
		ImageUtil.resize(srcpath,bigImgPath, targetWidth, targetHeight);
		return true;
	}

	/**
	 * 生成艺术家头像小图
	 * @param imgPath 原图地址
     * @param smallImgPath 小图文件地址
     * @param sharpId 形状
	 */
	protected boolean writePainterSmallImage(String srcpath, String smallImgPath) throws Exception {
		
		File f = new File(srcpath);
		BufferedImage sourceImage = ImageIO.read(f);
		
		int prevW = sourceImage.getWidth();
        int prevH = sourceImage.getHeight();
		
		int targetWidth= 0;
		int targetHeight = 0;

		if(prevW < 70.00) {
			targetWidth = prevW;
			targetHeight = prevH;
		}else{
			targetWidth = 70;
			targetHeight = targetWidth*prevH/prevW;
		}
		
		ImageUtil.resize(srcpath,smallImgPath, targetWidth, targetHeight);
		return true;
	}
    
    /**
     * 创建中图A
     * @param srcpath 原图路径
     * @param subpath 目标图像路径
     * @param sharpId 形状编号
     */
    protected boolean  writeMiddleImageA(String srcpath,String subpath,Long sharpId) throws Exception{
    	
		File f = new File(srcpath);
		if( !f.exists() ){
			return false;
		}
		
		BufferedImage sourceImage = ImageIO.read(f);
		int prevW = sourceImage.getWidth();
        int prevH = sourceImage.getHeight();
        if( sharpId == null ){
        	if(prevW < prevH){
        		sharpId = 2L;
        	}
        	else if(prevW > prevH){
        		sharpId = 3L;
        	}else{
        		sharpId = 1L;
        	}
        }
		
		int targetWidth= 0;
		int targetHeight = 0;
		if(sharpId == 1){//正方形
			if(prevH< 230.00){
				targetWidth = prevW;
				targetHeight = prevH;
			}else{
				targetHeight = 230;
				targetWidth = targetHeight*prevW/prevH;
			}
		}
		else if(sharpId == 2){//长方形(竖)
			if(prevW < 195.00){
				targetWidth = prevW;
				targetHeight = prevH;
			}else{
				targetWidth = 195;
				targetHeight = targetWidth*prevH/prevW;
			}
		}
		else if(sharpId == 3){//长方形(横)
			if(prevH< 230.00){
				targetWidth = prevW;
				targetHeight = prevH;
			}else{
				targetHeight = 230;
				targetWidth = targetHeight*prevW/prevH;
			}
		}
		
		ImageUtil.resize(srcpath,subpath, targetWidth, targetHeight);
		return true;
	}
    
    /**
     * 创建小图
     * @param srcpath 原图path
     * @param subpath 目标图片path
     * @param sharpId 形状
     */
    protected boolean  writeSmallImage(String srcpath,String subpath,Long sharpId) throws Exception{
    	
		File f = new File(srcpath);
		if( !f.exists() ){
			return false;
		}
		
		BufferedImage sourceImage = ImageIO.read(f);
		int prevW = sourceImage.getWidth();
        int prevH = sourceImage.getHeight();
        if( sharpId == null ){
        	if(prevW < prevH){
        		sharpId = 2L;
        	}
        	else if(prevW > prevH){
        		sharpId = 3L;
        	}else{
        		sharpId = 1L;
        	}
        }
		
		int targetWidth= 0;
		int targetHeight = 0;
		if(sharpId == 1){//正方形
			targetHeight = 80;
			targetWidth = targetHeight * prevW /prevH;
		}
		else if(sharpId == 2){//长方形(竖)
			targetWidth = 64;
			targetHeight = targetWidth*prevH/prevW;
		}
		else if(sharpId == 3){//长方形(横)
			targetHeight = 80;
			targetWidth = targetHeight * prevW /prevH;
		}
		
		ImageUtil.resize(srcpath,subpath, targetWidth, targetHeight);
		return true;
		
	}
    
    /**
     * @param file 上传的文件
     * @param originalName 原始文件名
     * @param sharpId  形状编号
     * @param newNameUploaded  新文件名
     * @param memo 备注
     */
    protected ImageInfo buildImage(File file,String originalName,String sharpId,String newNameUploaded,String... memo){
    	
    	if( file == null ) return null;
    	
		ImageInfo imageInfo = new ImageInfo();
		imageInfo.setNewNameUploaded(newNameUploaded);
		imageInfo.setOriginalName(originalName);
		String suffix =  StringUtil.getExt(file.getName());
		imageInfo.setSuffix(suffix);
		if(sharpId != null){
			imageInfo.setSharpId(Long.valueOf(sharpId));
		}
		if( memo != null && memo.length > 0){
			imageInfo.setMemo(memo[0]);
		}
		return imageInfo;
    }
    
    protected LogInfo buildLogInfo(LogTypeEnum type,String content) {
    	
    	LogInfo logInfo = new LogInfo();
    	String loginIp = request.getRemoteAddr();
    	logInfo.setCreateDate(Calendar.getInstance().getTime());
    	logInfo.setContent(content);
    	logInfo.setLoginIp(loginIp);
    	logInfo.setType(type.toString());
    	
    	User user = (User) session.getAttribute(Constants.Userinfo);
    	if( user != null){
    		logInfo.setUserCode(String.valueOf(user.getId()));
    		logInfo.setUserName(user.getUsername());
    	}
    	
    	logInfo.setMemo("0");
    	return logInfo;
	}
    
    protected LogInfo buildCustomerLogInfo(CustomerLogTypeEnum type,String content) {
    	
    	LogInfo logInfo = new LogInfo();
    	String loginIp = request.getRemoteAddr();
    	logInfo.setCreateDate(Calendar.getInstance().getTime());
    	logInfo.setContent(content);
    	logInfo.setLoginIp(loginIp);
    	logInfo.setType(type.toString());
    	
    	CustomerInfo customerInfo = (CustomerInfo) session.getAttribute(Constants.CustomerInfo);
    	if( customerInfo != null){
    		logInfo.setUserCode(String.valueOf(customerInfo.getId()));
    		logInfo.setUserName(customerInfo.getUserName());
    	}
    	
    	logInfo.setMemo("1");
    	return logInfo;
	}
    
    /** 图片生成路径  **/
    protected String getImageGeneratePath(){
    	return Constants.Image_generate_path;
    }
    
    /**** 图片上传路径  *****/
    protected String getImageUploadPath(){
    	return Constants.Image_upload_path;
    }
    
    /**
     * 重命名图片，得到一个随机数的名称
     */
    protected String getRandomImageFileName(){
    	return DateUtil.toString(DateUtil.getNow(), "yyMMddHHmmss")+ StringUtil.getRandStr(6);
    }
    
    protected void writeImg(ImageInfo img,String fold){
		if( img != null){
			String originalPath = getImageUploadPath()+"/"+img.getNewNameUploaded();
			String destPath = getImageGeneratePath() +"/"+fold+"/"+img.getId()+"."+ img.getSuffix();
			FileUtil.copyFile(originalPath, destPath);
		}
	}
    
    /**
     * 第一次生成作品图片
     * @throws Exception
     */
    protected void generateImageOfPaintingFirstTime(Painting painting,ImageInfo img) throws Exception{
    	if(img == null) return;
    	
    	Long sharpId = img.getSharpId();
		long image_id = img.getId();
		String suffix = img.getSuffix();
		
		CatalogType catalogType = painting.getCatalogType();
		Painter painter = painting.getPainter();
		String absolutePath  = getImageGeneratePath();
		String uploadedPath  = getImageUploadPath();
		if( catalogType != null){
			String foldName = "";
			if( 1 == catalogType.getId() ||  2 == catalogType.getId()){
				if( painter != null ){
					if( "2".equals(painter.getType())){//名家名画
						foldName = "/painting/"+painter.getId()+"/";
						String originalImgPath = absolutePath +foldName+image_id+"."+suffix ;//原图
						String middleImgAPath = absolutePath+foldName+image_id +"_m_a."+suffix ;//列表页面中图
						String smallImgPath = absolutePath+foldName+image_id +"_s."+ suffix ;//小图
						FileUtil.copyFile(uploadedPath+"/"+img.getNewNameUploaded(),originalImgPath);
						writeMiddleImageA(originalImgPath, middleImgAPath,sharpId);
						writeSmallImage(originalImgPath, smallImgPath,sharpId);
						return;
					}else{
						foldName = "/shuhua/"+painter.getId()+"/";;
					}
				}else{
					foldName = "/shuhua/";
				}
				String originalImgPath = absolutePath +foldName+image_id+"."+suffix ;//原图
				String middleImgAPath = absolutePath+foldName+image_id +"_m_a."+suffix ;//列表页面中图
				String middleImgBPath = absolutePath+foldName+image_id +"_m_b."+suffix ;//中图2
				String smallImgPath = absolutePath+foldName+image_id +"_s."+ suffix ;//小图
				FileUtil.copyFile(uploadedPath+"/"+img.getNewNameUploaded(),originalImgPath);
				writeMiddleImageA(originalImgPath,middleImgAPath , sharpId);
				writeCiyiMiddleImageB(originalImgPath, middleImgBPath, sharpId);
				writeSmallImage(originalImgPath, smallImgPath, sharpId);
				return;
			}
			else if( catalogType.getId() >= 3 ){
				CatalogTypeManager catalogTypeManager = SpringContextHolder.getBean("catalogTypeManager");
				catalogType = catalogTypeManager.get(catalogType.getId());
				foldName = "/"+catalogType.getEnglish_name()+"/";
				if( painter != null){
					foldName += painter.getId()+"/";
				}
		    }
			String originalImgPath = absolutePath +foldName+image_id+"."+suffix ;
			String middleImgAPath = absolutePath+foldName+image_id +"_m_a."+suffix ;
			String middleImgBPath = absolutePath+foldName+image_id +"_m_b."+suffix ;
			String smallImgPath = absolutePath+foldName+image_id +"_s."+ suffix ;
			FileUtil.copyFile(uploadedPath+"/"+img.getNewNameUploaded(),originalImgPath);
			writeMiddleImageA(originalImgPath,middleImgAPath , sharpId);
			writeCiyiMiddleImageB(originalImgPath, middleImgBPath, sharpId);
			writeSmallImage(originalImgPath, smallImgPath, sharpId);
		}else{
			String foldName = "/painting/";
			if( painter != null ){
				foldName += painter.getId()+"/";
			}
			String originalImgPath = absolutePath +foldName+image_id+"."+suffix ;//原图
			String middleImgAPath = absolutePath+foldName+image_id +"_m_a."+suffix ;//列表页面中图
			String smallImgPath = absolutePath+foldName+image_id +"_s."+ suffix ;//小图
			FileUtil.copyFile(uploadedPath+"/"+img.getNewNameUploaded(),originalImgPath);
			writeMiddleImageA(originalImgPath, middleImgAPath,sharpId);
			writeSmallImage(originalImgPath, smallImgPath,sharpId);
		}
	}
    
    /**
     * 第一次生成作者头像
     * @throws Exception
     */
    protected void generateImageOfPainterFirstTime(ImageInfo img) throws Exception{
		if( img != null){
			String fold = "painter";
			String originalPath = getImageUploadPath()+"/"+img.getNewNameUploaded();
			String smallImgPath = getImageGeneratePath()+"/"+fold+"/"+img.getId() +"_s."+ img.getSuffix() ;//小图
			String destPath = getImageGeneratePath() +"/"+fold+"/"+img.getId()+"."+ img.getSuffix();
			FileUtil.copyFile(originalPath, destPath);
			writePainterSmallImage(destPath, smallImgPath);
		}
    }
    
	public String getSort() {
		return sort;
	}

	public void setSort(String sort) {
		this.sort = sort;
	}

	public String getDir() {
		return dir;
	}

	public void setDir(String dir) {
		this.dir = dir;
	}

	public String getFilterTxt() {
		return filterTxt;
	}

	public void setFilterTxt(String filterTxt) {
		this.filterTxt = filterTxt;
	}

	public String getFilterValue() {
		return filterValue;
	}

	public void setFilterValue(String filterValue) {
		this.filterValue = filterValue;
	}

	public Page getPage() {
		return page;
	}

	public void setPage(Page page) {
		this.page = page;
	}

	public Integer getCurPage() {
		return curPage;
	}

	public void setCurPage(Integer curPage) {
		this.curPage = curPage;
	}

	public Integer getPageSize() {
		return pageSize;
	}

	public void setPageSize(Integer pageSize) {
		this.pageSize = pageSize;
	}
}